package com.yunmai.steplibrary;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import com.fyspring.stepcounter.dao.StepDataDao;
import com.fyspring.stepcounter.utils.TimeUtil;
import com.yunmai.steplibrary.db.StepBean;
import com.yunmai.steplibrary.utils.Log;
import java.text.SimpleDateFormat;
import java.util.Date;

public class StepService extends Service implements SensorEventListener {
  private static final String TAG = "StepService";
  public static final int STEP_CHANNEL_ID = 1;
  public static final String STEP_CHANNEL = "step_channel";// 通知渠道的id
  private String currentDate = "";

  private SensorManager sensorManager;
  private int stepSensor; // 0 计步传感器  1 加速度传感器（无总数，每次）
  private StepDataDao stepDataDao;
  private StepReceiver stepReceiver;
  private NotificationManager mNotificationManager;
  private NotificationCompat.Builder notificationBuilder;
  private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");

  private StepCounterBinder binder;

  public Runnable saveStepRunable = new Runnable() {
    @Override public void run() {
      saveStepData();
    }
  };

  public Runnable CheckStepRunable = new Runnable() {
    @Override public void run() {
      saveStepData();
      isNewDay();
    }
  };
  private Handler handler;

  @Nullable @Override public IBinder onBind(Intent intent) {
    binder = new StepCounterBinder();
    return binder;
  }

  @Override public void onCreate() {
    super.onCreate();
    handler = new Handler(getMainLooper());
    Log.debug("step", "tubage:onCreate ....");
    stepReceiver = new StepReceiver(this, saveStepRunable, CheckStepRunable);
    stepReceiver.init();
    initTodayData();
    initStepDetector();


  }

  private void postInitStep() {
    handler.postDelayed(new Runnable() {
      @Override public void run() {
        if(binder!=null){
          Log.debug("step",
              "tubage:postInitStep "+ currentStep+" 步数！");
          binder.notifyCallBack(currentStep,0);
        }
      }
    },500);
  }

  @Override public int onStartCommand(Intent intent, int flags, int startId) {
    int type = intent.getIntExtra("type", 1);
    Log.debug("step",
        "tubage:onStartCommand the create notification type is " + type + "--" + (type == 1 ? "true"
            : "false"));
    if (type == 1) {
      createNotificationChannel();
    } else {
      createErrorNotification();
    }

    postInitStep();

    return super.onStartCommand(intent, flags, startId);
  }

  private void createErrorNotification() {
    Notification notification = new Notification.Builder(this).build();
    startForeground(STEP_CHANNEL_ID, notification);
  }

  private void createNotificationChannel() {
    mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    // 用户可以看到的通知渠道的名字.
    CharSequence name = getString(R.string.channel_name);
    // 用户可以看到的通知渠道的描述
    String description = getString(R.string.channel_description);
    int importance = NotificationManager.IMPORTANCE_HIGH;
    NotificationChannel mChannel = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
      mChannel = new NotificationChannel(STEP_CHANNEL, name, importance);
      mChannel.setDescription(description);
      //设置通知出现时的闪灯（如果 android 设备支持的话）
      mChannel.enableLights(false);
      //mChannel.setLightColor(Color.RED);
      //设置通知出现时的震动（如果 android 设备支持的话）
      mChannel.enableVibration(false);
      //mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
      //最后在notificationmanager中创建该通知渠道 //
      mNotificationManager.createNotificationChannel(mChannel);
      //配置通知渠道的属性
      // 为该通知设置一个id
      Log.debug("step", "tubage:the create createNotificationChannel  " + mChannel);
      notificationBuilder = new NotificationCompat.Builder(this,
          STEP_CHANNEL);
      // 通知渠道的id
      notificationBuilder.setOngoing(true);
      Notification notifycation = notificationBuilder.setContentTitle("云麦计步器")
          .setContentText("当前还没有步数")
          .setSmallIcon(R.mipmap.ic_launcher)
          .setVibrate(new long[]{0})
          .setOnlyAlertOnce(true)//仅一次铃声
          .build();
      startForeground(STEP_CHANNEL_ID, notifycation);
      Log.debug("step", "tubage:the create createNotificationChannel ok!!! ");
    }
  }

  @Override public void onDestroy() {
    stopForeground(true);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
      if(mNotificationManager!=null) {
        mNotificationManager.cancel(STEP_CHANNEL_ID);
      }
    }

    if (stepReceiver != null) {
      stepReceiver.unInit();
    }

    Log.debug("step", "tubage:onDestroy ok!!! ");
  }

  /**
   * 传感器实例 注册
   */
  private void initStepDetector() {
    if (sensorManager != null) {
      sensorManager = null;
    }
    // 获取传感器管理器的实例
    sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    //android4.4以后可以使用计步传感器
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      Log.debug("step", "tubage:getStepDetector > KITKAT!!! ");
      boolean isone =
          getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_COUNTER);
      boolean istwo =
          getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_DETECTOR);
      Log.debug("step", "tubage:initStepSensor!!! ");
      Sensor countSensor =
          sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);//计步器（一般是开机后，记录历史步数累加值）
      Sensor detectorSensor =
          sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);//检测器（检测每次步伐数据）
      if (isone && countSensor != null) {
        stepSensor = 0;
        Log.debug("step", "tubage:initStepSensor counter ok !!! ");
        sensorManager.registerListener(StepService.this, countSensor,
            SensorManager.SENSOR_DELAY_NORMAL);
      } else if (istwo && detectorSensor != null) {
        stepSensor = 1;
        Log.debug("step", "tubage:initStepSensor detector ok!!! ");
        sensorManager.registerListener(StepService.this, detectorSensor,
            SensorManager.SENSOR_DELAY_NORMAL);
      }else{
        Log.debug("step", "tubage:no support step CounterSensor!!! ");
      }
    }
  }

  //是否有当天的记录
  private boolean hasRecord = false;
  //未记录之前的步数
  private int hasStepCount = 0;
  //下次记录之前的步数
  private int previousStepCount = 0;
  //当前步数
  private int currentStep = 0;

  @Override public void onSensorChanged(SensorEvent sensorEvent) {
    Log.debug("step", "tubage:onSensorChanged...." + simpleDateFormat.format(sensorEvent.timestamp /1000000)+ " stepSensor:" + stepSensor);
    if (stepSensor == 0) {
      int tempStep = (int) sensorEvent.values[0];
      if (!hasRecord) {
        hasRecord = true;
        hasStepCount = tempStep;
        Log.debug("step", "tubage:onSensorChanged Counter first:" + hasStepCount);
      } else {
        int thisStepCount = tempStep - hasStepCount;
        currentStep += (thisStepCount - previousStepCount);
        Log.debug("step", "tubage:onSensorChanged Counter:CURRENT_STEP:"
            + currentStep
            + " lastStep:"
            + previousStepCount);
        previousStepCount = thisStepCount;
      }

      saveStepRunable.run();
    } else if (stepSensor == 1) {
      if (sensorEvent.values[0] == 1.0) {
        currentStep++;
        Log.debug("step", "tubage:onSensorChanged Detector: CURRENT_STEP:" + currentStep+" 时间:"+ simpleDateFormat.format(sensorEvent.timestamp/1000000));

        saveStepRunable.run();
      }
    }
  }

  /**
   * 监听晚上0点变化初始化数据
   */
  private void isNewDay() {
    String time = "00:00";
    String newDate =  TimeUtil.Companion.getCurrentDate();
    Log.debug("setp","isNewDay :"+newDate+" currentDate:"+currentDate);

    if (time.equals(new SimpleDateFormat("HH:mm").format(new Date())) ||
        !currentDate.equals(newDate)) {
      Log.debug("step","tubage:isNewDay ok!!");
      initTodayData();
    }
  }

  /**
   * 初始化当天数据
   */
  private void initTodayData() {
    //获取当前时间
    currentDate = TimeUtil.Companion.getCurrentDate();

    //获取数据库
    stepDataDao = new StepDataDao(getApplicationContext());
    //获取当天的数据，用于展示
    StepBean data = stepDataDao.getCurDataByDate(currentDate);

    //为空则说明还没有该天的数据，有则说明已经开始当天的计步了
    if (data == null) {
      currentStep = 0;
      Log.debug("step","tubage: isnewData currentStep = 0!");
    } else {
      currentStep = Integer.parseInt(data.getSteps());
    }


    Log.debug("step","tubage:initTodayData currentDate:" + currentDate+" currentStep:"+currentStep);
  }

  /**
   * 保存当天的数据到数据库中，并去刷新通知栏
   */
  private void saveStepData() {
    Log.debug("step","tubage:saveStepData start!");
    //查询数据库中的数据
    StepBean stepBean = stepDataDao.getCurDataByDate(currentDate);
    //为空则说明还没有该天的数据，有则说明已经开始当天的计步了
    if (stepBean == null) {
      //没有则新建一条数据
      stepBean = new StepBean();
      stepBean.setCurDate(currentDate);
      stepBean.setSteps(currentStep + "");
      Log.debug("step","tubage:saveStepData addNew currentStep:"+currentStep+" currentDate:"+currentDate);

      stepDataDao.addNewData(stepBean);
    } else {
      //有则更新当前的数据
      if(!String.valueOf(currentStep).equals(stepBean.getSteps())) {
        stepBean.setSteps(currentStep + "");
        Log.debug("step","tubage:saveStepData update currentStep:" + currentStep);
        stepDataDao.updateCurData(stepBean);
      }
    }
    Log.debug("step","tubage:saveStepData over!");

    setStepBuilder();
  }

  private void setStepBuilder() {
    if(binder!=null){
      binder.notifyCallBack(0,currentStep);
    }

    if(notificationBuilder!=null) {
      notificationBuilder.setContentTitle("喔，厉害了，继续加油")
          .setContentText("今日总步数" + currentStep + "步")
          .setSmallIcon(R.mipmap.ic_launcher)
          .setVibrate(new long[]{0})
          .setOnlyAlertOnce(true)
          .build();
      mNotificationManager.notify(STEP_CHANNEL_ID, notificationBuilder.build());
    }
  }

  @Override public void onAccuracyChanged(Sensor sensor, int i) {
    //传感器精度的改变：
    //这种情况中，系统会调用onAccuracyChanged()方法，它提供了你要引用的发生精度变化的Sensor对象。
    //精度使用以下四个状态常量之一来代表的：
    //SENSOR_STATUS_ACCURACY_LOW
    //SENSOR_STATUS_ACCURACY_MEDIUM
    //SENSOR_STATUS_ACCURACY_HIGH
    //SENSOR_STATUS_UNRELIABLE
    Log.debug("step", "tubage:onAccuracyChanged .....");
  }
}
